package com.rd.animation.type;

import com.rd.animation.controller.ValueController;
import com.rd.animation.data.type.ScaleAnimationValue;
import com.rd.utils.AnimatorUtils;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;

public class ScaleAnimation extends ColorAnimation {
    public static final float DEFAULT_SCALE_FACTOR = 0.7f;
    public static final float MIN_SCALE_FACTOR = 0.3f;
    public static final float MAX_SCALE_FACTOR = 1;

    static final String ANIMATION_SCALE_REVERSE = "ANIMATION_SCALE_REVERSE";
    static final String ANIMATION_SCALE = "ANIMATION_SCALE";

    int radius;
    float scaleFactor;

    private ScaleAnimationValue value;

    public ScaleAnimation(ValueController.UpdateListener listener) {
        super(listener);
        value = new ScaleAnimationValue();
    }

    @Override
    public ValueAnimator createAnimator() {
        ValueAnimator animator = new ValueAnimator();
        animator.setDuration(BaseAnimation.DEFAULT_ANIMATION_TIME);
        animator.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
        animator.setValueUpdateListener(
                new AnimatorValue.ValueUpdateListener() {
                    @Override
                    public void onUpdate(AnimatorValue animatorValue, float v) {
                        animator.onUpdate(animatorValue, v);
                        onAnimateUpdated(animatorValue);
                    }
                });

        return animator;
    }

    public ScaleAnimation with(int colorStart, int colorEnd, int radius, float scaleFactor) {
        if (animator != null && hasChanges(colorStart, colorEnd, radius, scaleFactor)) {
            this.colorStart = colorStart;
            this.colorEnd = colorEnd;

            this.radius = radius;
            this.scaleFactor = scaleFactor;

            PropertyValuesHolder colorHolder = createColorPropertyHolder(false);
            PropertyValuesHolder reverseColorHolder = createColorPropertyHolder(true);

            PropertyValuesHolder scaleHolder = createScalePropertyHolder(false);
            PropertyValuesHolder scaleReverseHolder = createScalePropertyHolder(true);
            animator.setInnerListener(
                    new InnerValueUpdateListener() {
                        @Override
                        public void onUpdate(AnimatorValue animatorValue, float f) {
                            color = AnimatorUtils.getColor(f, colorHolder.getStartValue(), colorHolder.getEndValue());
                            colorReverse =
                                    AnimatorUtils.getColor(
                                            f, reverseColorHolder.getStartValue(), reverseColorHolder.getEndValue());
                            radiusValue =
                                    AnimatorUtils.getIntValue(
                                            scaleHolder.getStartValue(), scaleHolder.getEndValue(), f);
                            radiusReverse =
                                    AnimatorUtils.getIntValue(
                                            scaleReverseHolder.getStartValue(), scaleReverseHolder.getEndValue(), f);
                        }
                    });
            //            animator.setValues(colorHolder, reverseColorHolder, scaleHolder, scaleReverseHolder);
        }

        return this;
    }

    private int color;
    private int colorReverse;
    private int radiusValue;
    private int radiusReverse;
    private void onAnimateUpdated(AnimatorValue animation) {
        value.setColor(color);
        value.setColorReverse(colorReverse);

        value.setRadius(radiusValue);
        value.setRadiusReverse(radiusReverse);

        if (listener != null) {
            listener.onValueUpdated(value);
        }
    }

    protected PropertyValuesHolder createScalePropertyHolder(boolean isReverse) {
        int startRadiusValue;
        int endRadiusValue;

        if (isReverse) {
            startRadiusValue = radius;
            endRadiusValue = (int) (radius * scaleFactor);
        } else {
            startRadiusValue = (int) (radius * scaleFactor);
            endRadiusValue = radius;
        }

        PropertyValuesHolder holder = PropertyValuesHolder.ofInt(startRadiusValue, endRadiusValue);

        return holder;
    }

    @SuppressWarnings("RedundantIfStatement")
    private boolean hasChanges(int colorStart, int colorEnd, int radiusValue, float scaleFactorValue) {
        if (this.colorStart != colorStart) {
            return true;
        }

        if (this.colorEnd != colorEnd) {
            return true;
        }

        if (radius != radiusValue) {
            return true;
        }

        if (scaleFactor != scaleFactorValue) {
            return true;
        }

        return false;
    }
}
